<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
<meta name="viewport" content="width=device-width">
<meta name="theme-color" content="#222"><meta name="generator" content="Hexo 7.3.0">

  <link rel="apple-touch-icon" sizes="180x180" href="/images/apple-touch-icon-next.png">
  <link rel="icon" type="image/png" sizes="32x32" href="/images/favicon-32x32.ico">
  <link rel="icon" type="image/png" sizes="16x16" href="/images/favicon-16x16.ico">
  <link rel="mask-icon" href="/images/logo.svg" color="#222">

<link rel="stylesheet" href="/css/main.css">



<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.1/css/all.min.css" integrity="sha256-wiz7ZSCn/btzhjKDQBms9Hx4sSeUYsDrTLg7roPstac=" crossorigin="anonymous">
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/animate.css/3.1.1/animate.min.css" integrity="sha256-PR7ttpcvz8qrF57fur/yAx1qXMFJeJFiA6pSzWi0OIE=" crossorigin="anonymous">
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/fancyapps-ui/5.0.28/fancybox/fancybox.css" integrity="sha256-6cQIC71/iBIYXFK+0RHAvwmjwWzkWd+r7v/BX3/vZDc=" crossorigin="anonymous">
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/pace/1.2.4/themes/green/pace-theme-minimal.css">
  <script src="https://cdnjs.cloudflare.com/ajax/libs/pace/1.2.4/pace.min.js" integrity="sha256-gqd7YTjg/BtfqWSwsJOvndl0Bxc8gFImLEkXQT8+qj0=" crossorigin="anonymous"></script>

<script class="next-config" data-name="main" type="application/json">{"hostname":"sumumm.github.io","root":"/","images":"/images","scheme":"Gemini","darkmode":false,"version":"8.19.2","exturl":false,"sidebar":{"position":"left","display":"post","padding":18,"offset":12},"copycode":{"enable":true,"style":"mac"},"fold":{"enable":true,"height":300},"bookmark":{"enable":false,"color":"#222","save":"auto"},"mediumzoom":false,"lazyload":true,"pangu":false,"comments":{"style":"tabs","active":null,"storage":true,"lazyload":false,"nav":null},"stickytabs":false,"motion":{"enable":true,"async":true,"transition":{"menu_item":"fadeInDown","post_block":"fadeIn","post_header":"fadeInDown","post_body":"fadeInDown","coll_header":"fadeInLeft","sidebar":"fadeInUp"}},"i18n":{"placeholder":"搜索...","empty":"没有找到任何搜索结果：${query}","hits_time":"找到 ${hits} 个搜索结果（用时 ${time} 毫秒）","hits":"找到 ${hits} 个搜索结果"},"path":"/search.xml","localsearch":{"enable":true,"trigger":"auto","top_n_per_article":1,"unescape":false,"preload":false}}</script><script src="/js/config.js"></script>

    <meta name="description" content="本文主要是makefile——变量与目标相关笔记，若笔记中有错误或者不合适的地方，欢迎批评指正😃。">
<meta property="og:type" content="article">
<meta property="og:title" content="LV02-05-Makefile-02-变量和目标">
<meta property="og:url" content="https://sumumm.github.io/post/f9611cfe.html">
<meta property="og:site_name" content="苏木">
<meta property="og:description" content="本文主要是makefile——变量与目标相关笔记，若笔记中有错误或者不合适的地方，欢迎批评指正😃。">
<meta property="og:locale" content="zh_CN">
<meta property="article:published_time" content="2022-03-23T05:53:40.000Z">
<meta property="article:modified_time" content="2025-06-13T16:25:56.989Z">
<meta property="article:author" content="苏木">
<meta property="article:tag" content="LV02-编译基础">
<meta property="article:tag" content="makefile">
<meta name="twitter:card" content="summary">


<link rel="canonical" href="https://sumumm.github.io/post/f9611cfe.html">



<script class="next-config" data-name="page" type="application/json">{"sidebar":"","isHome":false,"isPost":true,"lang":"zh-CN","comments":true,"permalink":"https://sumumm.github.io/post/f9611cfe.html","path":"post/f9611cfe.html","title":"LV02-05-Makefile-02-变量和目标"}</script>

<script class="next-config" data-name="calendar" type="application/json">""</script>
<title>LV02-05-Makefile-02-变量和目标 | 苏木</title>
  








    <script src="/js/browser_tools_disable.js"></script>

  <noscript>
    <link rel="stylesheet" href="/css/noscript.css">
  </noscript>
<!-- hexo injector head_end start --><link rel="stylesheet" href="https://unpkg.com/hexo-next-tags-plus@latest/lib/tag_plus.css" media="defer" onload="this.media='all'"><!-- hexo injector head_end end --></head>

<body itemscope itemtype="http://schema.org/WebPage" class="use-motion">
  <div class="headband"></div>

  <main class="main">
    <div class="column">
      <header class="header" itemscope itemtype="http://schema.org/WPHeader"><div class="site-brand-container">
  <div class="site-nav-toggle">
    <div class="toggle" aria-label="切换导航栏" role="button">
        <span class="toggle-line"></span>
        <span class="toggle-line"></span>
        <span class="toggle-line"></span>
    </div>
  </div>

  <div class="site-meta">

    <a href="/" class="brand" rel="start">
      <i class="logo-line"></i>
      <p class="site-title">苏木</p>
      <i class="logo-line"></i>
    </a>
      <p class="site-subtitle" itemprop="description">我的学习之路</p>
  </div>

  <div class="site-nav-right">
    <div class="toggle popup-trigger" aria-label="搜索" role="button">
        <i class="fa fa-search fa-fw fa-lg"></i>
    </div>
  </div>
</div>



<nav class="site-nav">
  <ul class="main-menu menu"><li class="menu-item menu-item-home"><a href="/" rel="section"><i class="fa fa-home fa-fw"></i>苏木的家</a></li><li class="menu-item menu-item-categories"><a href="/categories/" rel="section"><i class="fa fa-th fa-fw"></i>分类页<span class="badge">42</span></a></li><li class="menu-item menu-item-archives"><a href="/archives/" rel="section"><i class="fa fa-archive fa-fw"></i>归档页<span class="badge">673</span></a></li><li class="menu-item menu-item-flink"><a href="/flink/" rel="section"><i class="fa fa-link fa-fw"></i>友人帐</a></li><li class="menu-item menu-item-about"><a href="/about/" rel="section"><i class="fa fa-user fa-fw"></i>关于我</a></li>
      <li class="menu-item menu-item-search">
        <a role="button" class="popup-trigger"><i class="fa fa-search fa-fw"></i>搜索
        </a>
      </li>
  </ul>
</nav>



  <div class="search-pop-overlay">
    <div class="popup search-popup"><div class="search-header">
  <span class="search-icon">
    <i class="fa fa-search"></i>
  </span>
  <div class="search-input-container">
    <input autocomplete="off" autocapitalize="off" maxlength="80"
           placeholder="搜索..." spellcheck="false"
           type="search" class="search-input">
  </div>
  <span class="popup-btn-close" role="button">
    <i class="fa fa-times-circle"></i>
  </span>
</div>
<div class="search-result-container no-result">
  <div class="search-result-icon">
    <i class="fa fa-spinner fa-pulse fa-5x"></i>
  </div>
</div>

    </div>
  </div>

</header>
        
  
  <aside class="sidebar">

    <div class="sidebar-inner sidebar-nav-active sidebar-toc-active">
      <ul class="sidebar-nav">
        <li class="sidebar-nav-toc">
          文章目录
        </li>
        <li class="sidebar-nav-overview">
          站点概览
        </li>
      </ul>

      <div class="sidebar-panel-container">
        <!--noindex-->
        <div class="post-toc-wrap sidebar-panel">
            <div class="post-toc animated"><ol class="nav"><li class="nav-item nav-level-1"><a class="nav-link" href="#%E4%B8%80%E3%80%81-Makefile-%E5%8F%98%E9%87%8F"><span class="nav-text">一、 Makefile 变量</span></a><ol class="nav-child"><li class="nav-item nav-level-2"><a class="nav-link" href="#1-%E5%8F%98%E9%87%8F%E7%9A%84%E5%AE%9A%E4%B9%89"><span class="nav-text">1. 变量的定义</span></a><ol class="nav-child"><li class="nav-item nav-level-3"><a class="nav-link" href="#1-1-%E5%AE%9A%E4%B9%89%E6%A0%BC%E5%BC%8F"><span class="nav-text">1.1 定义格式</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#1-2-%E4%BD%BF%E7%94%A8%E5%AE%9E%E4%BE%8B"><span class="nav-text">1.2 使用实例</span></a></li></ol></li><li class="nav-item nav-level-2"><a class="nav-link" href="#2-%E5%8F%98%E9%87%8F%E7%9A%84%E4%BD%BF%E7%94%A8"><span class="nav-text">2. 变量的使用</span></a><ol class="nav-child"><li class="nav-item nav-level-3"><a class="nav-link" href="#2-1-%E4%BD%BF%E7%94%A8%E6%A0%BC%E5%BC%8F"><span class="nav-text">2.1 使用格式</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#2-2-%E4%BD%BF%E7%94%A8%E5%AE%9E%E4%BE%8B"><span class="nav-text">2.2 使用实例</span></a></li></ol></li><li class="nav-item nav-level-2"><a class="nav-link" href="#3-%E5%8F%98%E9%87%8F%E7%9A%84%E8%B5%8B%E5%80%BC"><span class="nav-text">3. 变量的赋值</span></a><ol class="nav-child"><li class="nav-item nav-level-3"><a class="nav-link" href="#3-1-%E7%AE%80%E5%8D%95%E8%B5%8B%E5%80%BC"><span class="nav-text">3.1 简单赋值 :&#x3D; </span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#3-2-%E9%80%92%E5%BD%92%E8%B5%8B%E5%80%BC"><span class="nav-text">3.2 递归赋值 &#x3D; </span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#3-4-%E6%9D%A1%E4%BB%B6%E8%B5%8B%E5%80%BC"><span class="nav-text">3.4 条件赋值 ?&#x3D; </span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#3-5-%E8%BF%BD%E5%8A%A0%E8%B5%8B%E5%80%BC"><span class="nav-text">3.5 追加赋值</span></a></li></ol></li><li class="nav-item nav-level-2"><a class="nav-link" href="#4-%E9%A2%84%E5%AE%9A%E4%B9%89%E5%8F%98%E9%87%8F"><span class="nav-text">4. 预定义变量</span></a><ol class="nav-child"><li class="nav-item nav-level-3"><a class="nav-link" href="#4-1-%E5%B8%B8%E8%A7%81%E9%A2%84%E5%AE%9A%E4%B9%89%E5%8F%98%E9%87%8F"><span class="nav-text">4.1 常见预定义变量</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#4-2-%E4%BD%BF%E7%94%A8%E5%AE%9E%E4%BE%8B"><span class="nav-text">4.2 使用实例</span></a></li></ol></li><li class="nav-item nav-level-2"><a class="nav-link" href="#5-%E8%87%AA%E5%8A%A8%E5%8C%96%E5%8F%98%E9%87%8F"><span class="nav-text">5. 自动化变量</span></a><ol class="nav-child"><li class="nav-item nav-level-3"><a class="nav-link" href="#5-1-%E5%B8%B8%E7%94%A8%E8%87%AA%E5%8A%A8%E5%8C%96%E5%8F%98%E9%87%8F"><span class="nav-text">5.1 常用自动化变量</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#5-2-%E4%BD%BF%E7%94%A8%E5%AE%9E%E4%BE%8B"><span class="nav-text">5.2 使用实例</span></a></li></ol></li><li class="nav-item nav-level-2"><a class="nav-link" href="#6-%E5%8F%98%E9%87%8F%E9%AB%98%E7%BA%A7%E7%94%A8%E6%B3%95"><span class="nav-text">6. 变量高级用法</span></a><ol class="nav-child"><li class="nav-item nav-level-3"><a class="nav-link" href="#6-1-%E5%8F%98%E9%87%8F%E5%80%BC%E7%9A%84%E6%9B%BF%E6%8D%A2"><span class="nav-text">6.1 变量值的替换</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#6-2-%E5%8F%98%E9%87%8F%E5%B5%8C%E5%A5%97"><span class="nav-text">6.2 变量嵌套</span></a></li></ol></li><li class="nav-item nav-level-2"><a class="nav-link" href="#7-%E7%9B%AE%E6%A0%87%E5%8F%98%E9%87%8F"><span class="nav-text">7. 目标变量</span></a><ol class="nav-child"><li class="nav-item nav-level-3"><a class="nav-link" href="#7-1-%E4%BD%BF%E7%94%A8%E6%A0%BC%E5%BC%8F"><span class="nav-text">7.1 使用格式</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#7-2-%E4%BD%BF%E7%94%A8%E5%AE%9E%E4%BE%8B"><span class="nav-text">7.2 使用实例</span></a></li></ol></li></ol></li><li class="nav-item nav-level-1"><a class="nav-link" href="#%E4%BA%8C%E3%80%81Makefile-%E7%9B%AE%E6%A0%87"><span class="nav-text">二、Makefile 目标</span></a><ol class="nav-child"><li class="nav-item nav-level-2"><a class="nav-link" href="#1-%E7%89%B9%E6%AE%8A%E7%9B%AE%E6%A0%87"><span class="nav-text">1. 特殊目标</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#2-%E4%BC%AA%E7%9B%AE%E6%A0%87"><span class="nav-text">2.伪目标</span></a><ol class="nav-child"><li class="nav-item nav-level-3"><a class="nav-link" href="#2-1-%E4%B8%80%E4%B8%AA%E9%97%AE%E9%A2%98%EF%BC%9F"><span class="nav-text">2.1 一个问题？</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#2-2-%E6%80%8E%E4%B9%88%E5%8A%9E%E5%91%A2%EF%BC%9F"><span class="nav-text">2.2 怎么办呢？</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#2-3-%E6%88%90%E4%B8%BA%E4%BE%9D%E8%B5%96"><span class="nav-text">2.3 成为依赖</span></a></li></ol></li><li class="nav-item nav-level-2"><a class="nav-link" href="#3-%E5%A4%9A%E7%9B%AE%E6%A0%87"><span class="nav-text">3. 多目标</span></a><ol class="nav-child"><li class="nav-item nav-level-3"><a class="nav-link" href="#3-1-%E5%8D%95%E7%9B%AE%E6%A0%87%E6%B5%8B%E8%AF%95"><span class="nav-text">3.1 单目标测试</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#3-2-%E5%A4%9A%E7%9B%AE%E6%A0%87%E7%94%9F%E6%88%90%E6%96%B9%E5%BC%8F%E4%B8%80"><span class="nav-text">3.2 多目标生成方式一</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#3-3-%E5%A4%9A%E7%9B%AE%E6%A0%87%E7%94%9F%E6%88%90%E6%96%B9%E5%BC%8F%E4%BA%8C"><span class="nav-text">3.3 多目标生成方式二</span></a></li></ol></li><li class="nav-item nav-level-2"><a class="nav-link" href="#4-%E5%A4%9A%E8%A7%84%E5%88%99%E7%9B%AE%E6%A0%87"><span class="nav-text">4. 多规则目标</span></a><ol class="nav-child"><li class="nav-item nav-level-3"><a class="nav-link" href="#4-1-%E8%A7%84%E5%88%99"><span class="nav-text">4.1 :: 规则</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#4-2-%E4%BD%BF%E7%94%A8%E5%AE%9E%E4%BE%8B-1"><span class="nav-text">4.2 使用实例</span></a></li></ol></li></ol></li></ol></div>
        </div>
        <!--/noindex-->

        <div class="site-overview-wrap sidebar-panel">
          <div class="site-author animated" itemprop="author" itemscope itemtype="http://schema.org/Person">
    <img class="site-author-image" itemprop="image" alt="苏木"
      src="/images/avatar.jpg">
  <p class="site-author-name" itemprop="name">苏木</p>
  <div class="site-description" itemprop="description">莫道桑榆晚，为霞尚满天</div>
</div>
<div class="site-state-wrap animated">
  <nav class="site-state">
      <div class="site-state-item site-state-posts">
        <a href="/archives/">
          <span class="site-state-item-count">673</span>
          <span class="site-state-item-name">日志</span>
        </a>
      </div>
      <div class="site-state-item site-state-categories">
          <a href="/categories/">
        <span class="site-state-item-count">42</span>
        <span class="site-state-item-name">分类</span></a>
      </div>
      <div class="site-state-item site-state-tags">
        <span class="site-state-item-count">43</span>
        <span class="site-state-item-name">标签</span>
      </div>
  </nav>
</div>
  <div class="links-of-author animated">
      <span class="links-of-author-item">
        <a href="https://github.com/sumumm" title="GitHub → https:&#x2F;&#x2F;github.com&#x2F;sumumm" rel="noopener me" target="_blank"><i class="fab fa-github fa-fw"></i>GitHub</a>
      </span>
  </div>

        </div>
      </div>
    </div>

    
  </aside>


    </div>

    <div class="main-inner post posts-expand">


  


<div class="post-block">
  
  

  <article itemscope itemtype="http://schema.org/Article" class="post-content" lang="zh-CN">
    <link itemprop="mainEntityOfPage" href="https://sumumm.github.io/post/f9611cfe.html">

    <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
      <meta itemprop="image" content="/images/avatar.jpg">
      <meta itemprop="name" content="苏木">
    </span>

    <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
      <meta itemprop="name" content="苏木">
      <meta itemprop="description" content="莫道桑榆晚，为霞尚满天">
    </span>

    <span hidden itemprop="post" itemscope itemtype="http://schema.org/CreativeWork">
      <meta itemprop="name" content="LV02-05-Makefile-02-变量和目标 | 苏木">
      <meta itemprop="description" content="">
    </span>
      <header class="post-header">
        <h1 class="post-title" itemprop="name headline">
          LV02-05-Makefile-02-变量和目标
        </h1>

        <div class="post-meta-container">
          <div class="post-meta">
    <span class="post-meta-item">
      <span class="post-meta-item-icon">
        <i class="far fa-calendar"></i>
      </span>
      <span class="post-meta-item-text">发表于</span>

      <time title="创建时间：2022-03-23 13:53:40" itemprop="dateCreated datePublished" datetime="2022-03-23T13:53:40+08:00">2022-03-23</time>
    </span>
    <span class="post-meta-item">
      <span class="post-meta-item-icon">
        <i class="far fa-folder"></i>
      </span>
      <span class="post-meta-item-text">分类于</span>
        <span itemprop="about" itemscope itemtype="http://schema.org/Thing">
          <a href="/categories/%E5%B5%8C%E5%85%A5%E5%BC%8F%E5%BC%80%E5%8F%91/" itemprop="url" rel="index"><span itemprop="name">嵌入式开发</span></a>
        </span>
          ，
        <span itemprop="about" itemscope itemtype="http://schema.org/Thing">
          <a href="/categories/%E5%B5%8C%E5%85%A5%E5%BC%8F%E5%BC%80%E5%8F%91/01HQ%E8%AF%BE%E7%A8%8B%E4%BD%93%E7%B3%BB/" itemprop="url" rel="index"><span itemprop="name">01HQ课程体系</span></a>
        </span>
          ，
        <span itemprop="about" itemscope itemtype="http://schema.org/Thing">
          <a href="/categories/%E5%B5%8C%E5%85%A5%E5%BC%8F%E5%BC%80%E5%8F%91/01HQ%E8%AF%BE%E7%A8%8B%E4%BD%93%E7%B3%BB/LV02-%E7%BC%96%E8%AF%91%E5%9F%BA%E7%A1%80/" itemprop="url" rel="index"><span itemprop="name">LV02-编译基础</span></a>
        </span>
    </span>

  
    <span class="post-meta-break"></span>
    <span class="post-meta-item" title="本文字数">
      <span class="post-meta-item-icon">
        <i class="far fa-file-word"></i>
      </span>
      <span class="post-meta-item-text">本文字数：</span>
      <span>8.3k</span>
    </span>
    <span class="post-meta-item" title="阅读时长">
      <span class="post-meta-item-icon">
        <i class="far fa-clock"></i>
      </span>
      <span class="post-meta-item-text">阅读时长 &asymp;</span>
      <span>30 分钟</span>
    </span>
</div>

        </div>
      </header>

    
    
    
    <div class="post-body" itemprop="articleBody"><p>本文主要是makefile——变量与目标相关笔记，若笔记中有错误或者不合适的地方，欢迎批评指正😃。</p>
<span id="more"></span>

<!-- Photo: https://fanhua-picture.oss-cn-hangzhou.aliyuncs.com/01%E5%B5%8C%E5%85%A5%E5%BC%8F%E5%BC%80%E5%8F%91/01HQ%E8%AF%BE%E7%A8%8B%E4%BD%93%E7%B3%BB/LV02-%E7%BC%96%E8%AF%91%E5%9F%BA%E7%A1%80/LV02-05-Makefile-02-%E5%8F%98%E9%87%8F%E5%92%8C%E7%9B%AE%E6%A0%87/img/ -->

<details class="folding-tag" blue><summary> 点击查看使用工具及版本 </summary>
              <div class='content'>
              <table>    <tr>        <td align="center" width=150px>Windows</td>        <td align="left">windows11</td>    </tr>    <tr>        <td align="center">Ubuntu</td>        <td align="left">Ubuntu16.04的64位版本</td>      </tr>    <tr>        <td align="center">VMware® Workstation 16 Pro</td>        <td align="left">16.2.3 build-19376536</td>      </tr>    <tr>        <td align="center">SecureCRT</td>        <td align="left">Version 8.7.2 (x64 build 2214)   -   正式版-2020年5月14日</td>      </tr>    <tr>        <td align="center">开发板</td>        <td align="left">正点原子 i.MX6ULL Linux阿尔法开发板</td>      </tr>    <tr>        <td align="center">uboot</td>        <td align="left">NXP官方提供的uboot，NXP提供的版本为uboot-imx-rel_imx_4.1.15_2.1.0_ga(使用的uboot版本为U-Boot 2016.03)</td>      </tr>    <tr>        <td align="center">linux内核</td>        <td align="left">linux-4.15(NXP官方提供)</td>      </tr>    <tr>        <td align="center">STM32开发板</td>        <td align="left">正点原子战舰V3(STM32F103ZET6)</td>      </tr></table>
              </div>
            </details>

<details class="folding-tag" blue><summary> 点击查看本文参考资料 </summary>
              <div class='content'>
              <table>    <tr><td align="center">参考方向  </td><td align="center">参考原文</td></tr>    <tr><td align="left"> Makefile </td><td align="left"><a href="" target="_blank"> 跟我一起写Makefile <i class="fa fa-external-link-alt"></i> </a></td></tr></table>
              </div>
            </details>

<details class="folding-tag" blue><summary> 点击查看相关文件下载 </summary>
              <div class='content'>
              <table>    <tr>        <td align="center">---</td>        <td align="left">--- <a href="" target="_blank">  <i class="fa fa-external-link-alt"></i></a></td>      </tr></table>
              </div>
            </details>

<h1 id="一、-Makefile-变量"><a href="#一、-Makefile-变量" class="headerlink" title="一、 Makefile 变量"></a><font size=3>一、 Makefile 变量</font></h1><p>变量，我们并不陌生， Makefile 又不是编程语言，为什么也需要变量呢？我们什么需要创建变量呢？创建变量的目的其实就是用来代替一个文本字符串：</p>
<ul>
<li><p>（1）系列文件的名字 </p>
</li>
<li><p>（2）传递给编译器的参数 </p>
</li>
<li><p>（3）需要运行的程序 </p>
</li>
<li><p>（4）需要查找源代码的目录 </p>
</li>
<li><p>（5）你需要输出信息的目录 </p>
</li>
<li><p>（6）我们想做的其它事情。</p>
</li>
</ul>
<h2 id="1-变量的定义"><a href="#1-变量的定义" class="headerlink" title="1. 变量的定义"></a><font size=3>1. 变量的定义</font></h2><h3 id="1-1-定义格式"><a href="#1-1-定义格式" class="headerlink" title="1.1 定义格式"></a><font size=3>1.1 定义格式</font></h3><p>变量定义的基本格式如下：</p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">variable=value</span><br></pre></td></tr></table></figure>

<p>【说明】</p>
<p>（1）变量的不需要使用数据类型。变量的名称可以由大小写字母、阿拉伯数字和下划线构成。</p>
<p>（2）等号左右的空白符没有明确的要求，因为在执行  make  的时候多余的空白符会被自动的删除。</p>
<p>（3） value 表示值列表，既可以是零项，又可以是一项或者是多项。例如，</p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">VALUE_LIST = one two three</span><br></pre></td></tr></table></figure>

<p>（4）变量定义时是可以换行书写的，只是需要在每行结尾处添加一个 \ 。</p>
<h3 id="1-2-使用实例"><a href="#1-2-使用实例" class="headerlink" title="1.2 使用实例"></a><font size=3>1.2 使用实例</font></h3><details class="folding-tag" blue><summary> 点击查看换行书写实例 </summary>
              <div class='content'>
              <p> Makefile 文件内容如下：</p><figure class="highlight makefile"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">a = main.o \</span><br><span class="line">	 test.o \</span><br><span class="line">	 test.h</span><br><span class="line"></span><br><span class="line"><span class="section">test:</span></span><br><span class="line">	@echo <span class="string">&quot;a=<span class="variable">$(a)</span>&quot;</span></span><br></pre></td></tr></table></figure><p>然后在终端中执行 make test ，可以看到终端会有以下内容输出：</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">a=main.o test.o test.h</span><br></pre></td></tr></table></figure>
              </div>
            </details>

<h2 id="2-变量的使用"><a href="#2-变量的使用" class="headerlink" title="2. 变量的使用"></a><font size=3>2. 变量的使用</font></h2><h3 id="2-1-使用格式"><a href="#2-1-使用格式" class="headerlink" title="2.1 使用格式"></a><font size=3>2.1 使用格式</font></h3><p>上边定义的变量如何引用呢？引用格式如下：</p>
<figure class="highlight makefile"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="variable">$(VALUE_LIST)</span></span><br><span class="line"><span class="comment"># 或者</span></span><br><span class="line">$&#123;VALUE_LIST&#125;</span><br></pre></td></tr></table></figure>

<h3 id="2-2-使用实例"><a href="#2-2-使用实例" class="headerlink" title="2.2 使用实例"></a><font size=3>2.2 使用实例</font></h3><p>现在我们来试验一下，修改 Makefile 文件为以下内容：</p>
<figure class="highlight makefile"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line">OBJ = main.o test1.o test2.o</span><br><span class="line"><span class="section">main: $&#123;OBJ&#125;</span></span><br><span class="line">	gcc <span class="variable">$(OBJ)</span> -o main</span><br><span class="line"><span class="section">main.o: main.c test.h</span></span><br><span class="line">	gcc -c main.c -o main.o</span><br><span class="line"><span class="section">test1.o: test1.c test.h</span></span><br><span class="line">	gcc -c test1.c -o test1.o</span><br><span class="line"><span class="section">test2.o: test2.c test.h</span></span><br><span class="line">	gcc -c test2.c -o test2.o</span><br><span class="line"></span><br><span class="line"><span class="meta"><span class="keyword">.PHONY</span>: clean</span></span><br><span class="line"><span class="section">clean:</span></span><br><span class="line">	rm -rf *.o main</span><br></pre></td></tr></table></figure>

<details class="folding-tag" blue><summary> 点击查看相关文件内容 </summary>
              <div class='content'>
              <p><strong>【注意】</strong>目前所有文件都在同一个目录下。</p><div class="tabs" id="tabname1"><ul class="nav-tabs"><li class="tab active"><a href="#tabname1-1">main.c</a></li><li class="tab"><a href="#tabname1-2">test1.c</a></li><li class="tab"><a href="#tabname1-3">test2.c</a></li><li class="tab"><a href="#tabname1-4">test.h</a></li></ul><div class="tab-content"><div class="tab-pane active" id="tabname1-1"><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;stdio.h&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&quot;test.h&quot;</span></span></span><br><span class="line"></span><br><span class="line"><span class="type">int</span> <span class="title function_">main</span><span class="params">(<span class="type">int</span> argc, <span class="type">const</span> <span class="type">char</span> *argv[])</span></span><br><span class="line">&#123;</span><br><span class="line">	<span class="built_in">printf</span>(<span class="string">&quot;This is main file!\n&quot;</span>);</span><br><span class="line">	test1Fun();</span><br><span class="line">	test2Fun();</span><br><span class="line">	<span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure></div><div class="tab-pane" id="tabname1-2"><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;stdio.h&gt;</span></span></span><br><span class="line"></span><br><span class="line"><span class="type">void</span> <span class="title function_">test1Fun</span><span class="params">()</span></span><br><span class="line">&#123;</span><br><span class="line">    <span class="built_in">printf</span>(<span class="string">&quot;This is test1.c file\n&quot;</span>);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure></div><div class="tab-pane" id="tabname1-3"><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;stdio.h&gt;</span></span></span><br><span class="line"></span><br><span class="line"><span class="type">void</span> <span class="title function_">test2Fun</span><span class="params">()</span></span><br><span class="line">&#123;</span><br><span class="line">    <span class="built_in">printf</span>(<span class="string">&quot;This is test2.c file\n&quot;</span>);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure></div><div class="tab-pane" id="tabname1-4"><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="type">void</span> <span class="title function_">test1Fun</span><span class="params">()</span>;</span><br><span class="line"><span class="type">void</span> <span class="title function_">test2Fun</span><span class="params">()</span>;</span><br></pre></td></tr></table></figure></div></div></div>
              </div>
            </details>

<p>这里我使用了两种引用方式，用以说明两种引用方式均可。然后执行 make 命令，会发现，最后依然正常生成了文件。当我们要添加或者是删除某个依赖文件的时候，我们只需要改变变量 OBJ  的值就可以了。</p>
<h2 id="3-变量的赋值"><a href="#3-变量的赋值" class="headerlink" title="3. 变量的赋值"></a><font size=3>3. 变量的赋值</font></h2><p>上边我们定义变量的时候使用的符号是 &#x3D; ，但是其实在 Makefile 中，赋值方式有四种：</p>
<table>
    <tr><td align="center" width=100px>符号</td><td align="center">说明</td></tr>
    <tr><td align="center" width=100px>:=</td><td align="left">简单赋值，编程语言中常规理解的赋值方式，只对当前语句的变量有效。</td></tr>
    <tr><td align="center" width=100px>= </td><td align="left">递归赋值，赋值语句可能影响多个变量，所有目标变量相关的其他变量都受影响。</td></tr>
    <tr><td align="center" width=100px>?=</td><td align="left">条件赋值，如果变量未定义，则使用符号中的值定义变量。如果该变量已经赋值，则该赋值语句无效。</td></tr>
    <tr><td align="center" width=100px>+=</td><td align="left">追加赋值，原变量用空格隔开的方式追加一个新值。</td></tr>
</table>


<h3 id="3-1-简单赋值"><a href="#3-1-简单赋值" class="headerlink" title="3.1 简单赋值 :&#x3D; "></a><font size=3>3.1 简单赋值 :&#x3D; </font></h3><p>我们在 Makefile 文件中添加以下内容：</p>
<figure class="highlight makefile"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">a:=fanhua</span><br><span class="line">b:=$&#123;a&#125; 123456@qq.com <span class="string">&quot;fanhua&quot;</span></span><br><span class="line">a:=qidaink</span><br><span class="line"><span class="section">test:</span></span><br><span class="line">	@echo <span class="string">&quot;a=$&#123;a&#125;&quot;</span></span><br><span class="line">	@echo <span class="string">&quot;b=$&#123;b&#125;&quot;</span></span><br></pre></td></tr></table></figure>

<p>然后在终端中执行：</p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">make test</span><br></pre></td></tr></table></figure>

<p>会看到输出的结果如下：</p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">a=qidaink</span><br><span class="line">b=fanhua 123456@qq.com fanhua</span><br></pre></td></tr></table></figure>

<p>用这种方式定义的变量，会在变量的定义点，按照被引用的变量的当前值进行展开 。</p>
<h3 id="3-2-递归赋值"><a href="#3-2-递归赋值" class="headerlink" title="3.2 递归赋值 &#x3D; "></a><font size=3>3.2 递归赋值 &#x3D; </font></h3><p>我们在 Makefile 文件中添加以下内容：</p>
<figure class="highlight makefile"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">a=fanhua</span><br><span class="line">b=$&#123;a&#125; 123456@qq.com <span class="string">&quot;fanhua&quot;</span></span><br><span class="line">a=qidaink</span><br><span class="line"><span class="section">test:</span></span><br><span class="line">	@echo <span class="string">&quot;a=$&#123;a&#125;&quot;</span></span><br><span class="line">	@echo <span class="string">&quot;b=$&#123;b&#125;&quot;</span></span><br></pre></td></tr></table></figure>

<p>然后在终端中执行：</p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">make test</span><br></pre></td></tr></table></figure>

<p>会看到输出的结果如下：</p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">a=qidaink</span><br><span class="line">b=qidaink 123456@qq.com fanhua</span><br></pre></td></tr></table></figure>

<p>这意味着，即便 a 是在 b 后边进行了修改，但是变量 b 依然引用了 a 修改之后的值。这种赋值方式优点是可以向后引用变量，缺点是不能对该变量进行任何扩展，例如：</p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">a=fanhua</span><br><span class="line">b=$&#123;a&#125; 123456@qq.com &quot;fanhua&quot;</span><br><span class="line">a=$(a)</span><br></pre></td></tr></table></figure>

<p>这样会造成一种死循环，应该是会直接报错的：</p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">Makefile:3: *** Recursive variable &#x27;a&#x27; references itself (eventually)。 停止。</span><br></pre></td></tr></table></figure>



<h3 id="3-4-条件赋值"><a href="#3-4-条件赋值" class="headerlink" title="3.4 条件赋值 ?&#x3D; "></a><font size=3>3.4 条件赋值 ?&#x3D; </font></h3><p>我们在 Makefile 文件中添加以下内容：</p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">a:=fanhua</span><br><span class="line">b:=$&#123;a&#125; 123456@qq.com &quot;fanhua&quot;</span><br><span class="line">a?=qidaink</span><br><span class="line">test:</span><br><span class="line">	@echo &quot;a=$&#123;a&#125;&quot;</span><br><span class="line">	@echo &quot;b=$&#123;b&#125;&quot;</span><br></pre></td></tr></table></figure>

<p>然后在终端中执行：</p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">make test</span><br></pre></td></tr></table></figure>

<p>会看到输出的结果如下：</p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">a=fanhua</span><br><span class="line">b=fanhua 123456@qq.com fanhua</span><br></pre></td></tr></table></figure>

<p>若是将第一行的 a:&#x3D;fanhua 删除，则输出结果是这样的：</p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">a=qidaink</span><br><span class="line">b= 123456@qq.com fanhua</span><br></pre></td></tr></table></figure>

<p>这种赋值方式其实就等价于：</p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">ifeq ($(origin a), undefined)</span><br><span class="line">      a = bar</span><br><span class="line">endif</span><br></pre></td></tr></table></figure>

<p>【说明】什么是 ifeq ？其实是 Makefile 中的条件判断，后边会详细解释，这里简单了解下就可以了。</p>
<h3 id="3-5-追加赋值"><a href="#3-5-追加赋值" class="headerlink" title="3.5 追加赋值"></a><font size=3>3.5 追加赋值</font></h3><p>我们在 Makefile 文件中添加以下内容：</p>
<figure class="highlight makefile"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">a:=fanhua</span><br><span class="line">b:=$&#123;a&#125; 123456@qq.com <span class="string">&quot;fanhua&quot;</span></span><br><span class="line">a+=$&#123;b&#125;</span><br><span class="line"><span class="section">test:</span></span><br><span class="line">	@echo <span class="string">&quot;a=$&#123;a&#125;&quot;</span></span><br><span class="line">	@echo <span class="string">&quot;b=$&#123;b&#125;&quot;</span></span><br></pre></td></tr></table></figure>

<p>然后在终端中执行：</p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">make test</span><br></pre></td></tr></table></figure>

<p>会看到输出的结果如下：</p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">a=fanhua fanhua 123456@qq.com fanhua</span><br><span class="line">b=fanhua 123456@qq.com fanhua</span><br></pre></td></tr></table></figure>

<h2 id="4-预定义变量"><a href="#4-预定义变量" class="headerlink" title="4. 预定义变量"></a><font size=3>4. 预定义变量</font></h2><h3 id="4-1-常见预定义变量"><a href="#4-1-常见预定义变量" class="headerlink" title="4.1 常见预定义变量"></a><font size=3>4.1 常见预定义变量</font></h3><p>在 Makefile 中也存在着一些预定义变量：</p>
<table>
    <tr><td align="center" width=100px>AR</td><td align="left">库文件维护程序的名称，默认值为ar。AS汇编程序的名称，默认值为as。</td></tr>
    <tr><td align="center" width=100px>CC</td><td align="left">C编译器的名称，默认值为cc。CPP  C预编译器的名称，默认值为$(CC) –E。</td></tr>
    <tr><td align="center" width=100px>CXX</td><td align="left">C++编译器的名称，默认值为g++。</td></tr>
    <tr><td align="center" width=100px>FC</td><td align="left">FORTRAN编译器的名称，默认值为f77</td></tr>
    <tr><td align="center" width=100px>RM</td><td align="left">文件删除程序的名称，默认值为rm -f</td></tr>
    <tr><td align="center" width=100px>ARFLAGS</td><td align="left">库文件维护程序的选项，无默认值。</td></tr>
    <tr><td align="center" width=100px>ASFLAGS</td><td align="left">汇编程序的选项，无默认值。</td></tr>
    <tr><td align="center" width=100px>CFLAGS</td><td align="left">C编译器的选项，无默认值。</td></tr>
    <tr><td align="center" width=100px>CPPFLAGS</td><td align="left">C预编译的选项，无默认值。</td></tr>
    <tr><td align="center" width=100px>CXXFLAGS</td><td align="left">C++编译器的选项，无默认值。</td></tr>
    <tr><td align="center" width=100px>FFLAGS</td><td align="left">FORTRAN编译器的选项，无默认值。</td></tr>
</table>

<h3 id="4-2-使用实例"><a href="#4-2-使用实例" class="headerlink" title="4.2 使用实例"></a><font size=3>4.2 使用实例</font></h3><p>我们在 Makefile 文件中添加以下内容：</p>
<figure class="highlight makefile"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="section">test:</span></span><br><span class="line">	@echo <span class="string">&quot;CC = <span class="variable">$(CC)</span>&quot;</span></span><br><span class="line">	@echo <span class="string">&quot;AR = <span class="variable">$(AR)</span>&quot;</span></span><br><span class="line">	@echo <span class="string">&quot;RM = <span class="variable">$(RM)</span>&quot;</span></span><br><span class="line">	@echo <span class="string">&quot;CXX= <span class="variable">$(CXX)</span>&quot;</span></span><br></pre></td></tr></table></figure>

<p>然后在终端中执行：</p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">make test</span><br></pre></td></tr></table></figure>

<p>会看到输出的结果如下：</p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">CC = cc</span><br><span class="line">AR = ar</span><br><span class="line">RM = rm -f</span><br><span class="line">CXX= g++</span><br></pre></td></tr></table></figure>

<h2 id="5-自动化变量"><a href="#5-自动化变量" class="headerlink" title="5. 自动化变量"></a><font size=3>5. 自动化变量</font></h2><h3 id="5-1-常用自动化变量"><a href="#5-1-常用自动化变量" class="headerlink" title="5.1 常用自动化变量"></a><font size=3>5.1 常用自动化变量</font></h3><p>自动化变量可以理解为由  Makefile  自动产生的变量。</p>
<table>
    <tr><td align="center" width=100px>$*</td><td align="left">不包含扩展名的目标文件名称（当文件名中存在目录时，也会包含目录部分）。例如，<br>
        （1）main.o: main.c test.h中 $* 就代表 main 。<br>
        （2）如果目标是"dir/a.foo.b"，并且目标的模式是
"a.%.b"，那么，"$*"的值就是"dir/a.foo"。<br>【说明】在模式规则和静态模式规则中，代表“茎”。“茎”是目标模式中“%”所代表的部分（当文件名中存在目录时，
“茎”也包含目录部分）。</td></tr>
    <tr><td align="center" width=100px>$@</td><td align="left">表示规则的目标文件完整名称名。如果目标是一个文档文件（Linux 中，一般成 .a 文件为文档文件，也成为静态的库文件），那么它代表这个文档的文件名。在多目标模式规则中，它代表的是触发规则被执行的文件名。</td></tr>
    <tr><td align="center" width=100px>$%</td><td align="left">仅当目标是函数库文件中，表示规则中的目标成员名。例如，如果一个目标是"foo.a(bar.o)"，
那么，"$%"就是"bar.o"，"$@"就是"foo.a"。如果目标不是函数库文件（Unix 下是[.a]，Windows
下是[.lib]），那么，其值为空。
</td></tr>
    <tr><td align="center" width=100px>$&lt;</td><td align="left">规则的第一个依赖的文件名。如果是一个目标文件使用隐含的规则来重建，则它代表由隐含规则加入的第一个依赖文件。如果依赖目标是以模式（即 % ）定义的，那么 $&lt; 将是符合模式的一系列的文件集。注意，其是一个一个取出来执行的</td></tr>
    <tr><td align="center" width=100px>$?</td><td align="left">所有比目标文件更新的依赖文件列表，空格分隔。如果目标文件时静态库文件，代表的是库文件（.o 文件）。</td></tr>
    <tr><td align="center" width=100px>$^</td><td align="left">代表的是所有依赖文件列表，使用空格分隔。如果目标是静态库文件，它所代表的只能是所有的库成员（.o 文件）名。一个可重复的文件出现在目标的依赖中，变量“$^”只记录它的第一次引用的情况。就是说变量“$^”会去掉重复的依赖文件。</td></tr>
    <tr><td align="center" width=100px>$+</td><td align="left">所有的依赖文件，以空格分开。类似“$^”，但是它保留了依赖文件中重复出现的文件。主要用在程序链接时库的交叉引用场合。</td></tr>
</table>


<p>【说明】</p>
<p>（1）茎的概念在后边静态模式的笔记中会有说明。</p>
<p>（2）对于 $&lt; ，为了避免产生不必要的麻烦，我们最好给 $ 后面的那个特定字符都加上圆括号。</p>
<details class="folding-tag" blue><summary> 点击查看更为细致的引用方式说明 </summary>
              <div class='content'>
              <table>    <tr><td align="center" width=100px>变量名</td><td align="left">功能</td></tr>    <tr><td align="center" width=100px>$(@D)</td><td align="left">表示"$@"的目录部分（不以斜杠作为结尾），如果"$@"值是"dir/foo.o"，那么"$(@D)"就是"dir"，而如果"$@"中没有包含斜杠的话，其值就是"."（当前目录）。</td></tr>    <tr><td align="center" width=100px>$(@F)</td><td align="left">表示"$@"的文件部分，如果"$@"值是"dir/foo.o"，那么"$(@F)"就是"foo.o"，"$(@F)"相当于函数"$(notdir $@)"。</td></tr>    <tr><td align="center" width=100px>$(*D)</td><td align="left" rowspan="2">分别代表 "茎" 中的目录部分和文件名部分。</td></tr>    <tr><td align="center" width=100px>$(*F)</td></tr>    <tr><td align="center" width=100px>$(%D)</td><td align="left" rowspan="2">当以 "archive(member)" 形式静态库为目标时，分别表示库文件成员 "member" 名中的目录部分和文件名部分。踏</td></tr>    <tr><td align="center" width=100px>$(%F)</td></tr>    <tr><td align="center" width=100px>$(&lt;D)</td><td align="left" rowspan="2">表示第一个依赖文件的目录部分和文件名部分。</td></tr>    <tr><td align="center" width=100px>$(&lt;F)</td></tr>    <tr><td align="center" width=100px>$(^D)</td><td align="left" rowspan="2">分别表示所有依赖文件的目录部分和文件部分。（无相同的）</td></tr>    <tr><td align="center" width=100px>$(^F)</td></tr>    <tr><td align="center" width=100px>$(+D)</td><td align="left" rowspan="2">分别表示所有的依赖文件的目录部分和文件部分。（可以有相同的）</td></tr>    <tr><td align="center" width=100px>$(+F)</td></tr>    <tr><td align="center" width=100px>$(?D)</td><td align="left" rowspan="2">分别表示更新的依赖文件的目录部分和文件名部分。</td></tr>    <tr><td align="center" width=100px>$(?F)</td></tr></table>
              </div>
            </details>

<h3 id="5-2-使用实例"><a href="#5-2-使用实例" class="headerlink" title="5.2 使用实例"></a><font size=3>5.2 使用实例</font></h3><p>修改 Makefile 文件如下：</p>
<figure class="highlight makefile"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br></pre></td><td class="code"><pre><span class="line">OBJ= main.o test1.o test2.o</span><br><span class="line"><span class="section">main: $&#123;OBJ&#125;</span></span><br><span class="line">	gcc <span class="variable">$(OBJ)</span> -o main</span><br><span class="line"><span class="section">main.o: main.c test.h main.c</span></span><br><span class="line">	gcc -c main.c -o main.o</span><br><span class="line">	@echo <span class="string">&quot;* = <span class="variable">$*</span>&quot;</span></span><br><span class="line">	@echo <span class="string">&quot;@ = <span class="variable">$@</span>&quot;</span></span><br><span class="line">	@echo <span class="string">&quot;% = <span class="variable">$%</span>&quot;</span></span><br><span class="line">	@echo <span class="string">&quot;&lt; = <span class="variable">$&lt;</span>&quot;</span></span><br><span class="line">	@echo <span class="string">&quot;? = <span class="variable">$?</span>&quot;</span></span><br><span class="line">	@echo <span class="string">&quot;^ = <span class="variable">$^</span>&quot;</span></span><br><span class="line">	@echo <span class="string">&quot;+ = <span class="variable">$+</span>&quot;</span></span><br><span class="line"><span class="section">test1.o: test1.c test.h</span></span><br><span class="line">	gcc -c test1.c -o test1.o</span><br><span class="line"><span class="section">test2.o: test2.c test.h</span></span><br><span class="line">	gcc -c test2.c -o test2.o</span><br><span class="line"><span class="meta"><span class="keyword">.PHONY</span>: clean</span></span><br><span class="line"><span class="section">clean:</span></span><br><span class="line">	rm -rf *.o test</span><br></pre></td></tr></table></figure>

<p>执行以下命令：</p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">make clean</span><br><span class="line">make main.o</span><br></pre></td></tr></table></figure>

<p>输出结果如下：</p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line">gcc -c main.c -o main.o</span><br><span class="line">* = main</span><br><span class="line">@ = main.o</span><br><span class="line"><span class="meta prompt_">% </span><span class="language-bash">=</span> </span><br><span class="line">&lt; = main.c</span><br><span class="line">? = main.c test.h</span><br><span class="line">^ = main.c test.h</span><br><span class="line">+ = main.c test.h main.c</span><br><span class="line">gcc -c test1.c -o test1.o</span><br><span class="line">gcc -c test2.c -o test2.o</span><br><span class="line">gcc main.o test1.o test2.o -o main</span><br></pre></td></tr></table></figure>

<h2 id="6-变量高级用法"><a href="#6-变量高级用法" class="headerlink" title="6. 变量高级用法"></a><font size=3>6. 变量高级用法</font></h2><h3 id="6-1-变量值的替换"><a href="#6-1-变量值的替换" class="headerlink" title="6.1 变量值的替换"></a><font size=3>6.1 变量值的替换</font></h3><p>我们可以在引用的时候直接替换变量的值，可以直接替换变量中的共有的部分，一般格式如下：</p>
<figure class="highlight makefile"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 先定义一个变量，并简单赋值</span></span><br><span class="line">var1 := value_list</span><br><span class="line"></span><br><span class="line"><span class="comment"># 开始替换变量值</span></span><br><span class="line">var2 := $(var1:&lt;string1&gt;=&lt;string2&gt;)</span><br><span class="line"><span class="comment"># 或者</span></span><br><span class="line">var2 := $&#123;var1:&lt;string1&gt;=&lt;string2&gt;&#125;</span><br></pre></td></tr></table></figure>

<p>上边的含义就是，将变量 var1 中的所有以 string1 字符串结尾的变量值替换成以 string2 字符串结尾。</p>
<p>【注意】</p>
<p>（1）这里是<strong>结尾字符串的替换</strong>，其他位置的好像是不可以进行替换的。</p>
<p>（2）也可以使用模式规则进行替换，也就是通过 % 来匹配除需要替换的部分以外的字符串。</p>
<p>（3） var1:&lt;string1&gt;&#x3D;&lt;string2&gt; 这一部分的 : 和 &#x3D; 两端最好不要有空格，否则可能会出现问题。</p>
<details class="folding-tag" blue><summary> 点击查看实例 </summary>
              <div class='content'>
              <p> Makefile 文件内容如下：</p><figure class="highlight makefile"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">var1 := main.o test.o</span><br><span class="line">var2 := $(var1:.o=.c)</span><br><span class="line">var3 := $(var1:%.o=%.c)</span><br><span class="line"><span class="section">test:</span></span><br><span class="line">	@echo <span class="string">&quot;var1=<span class="variable">$(var1)</span>&quot;</span></span><br><span class="line">	@echo <span class="string">&quot;var2=<span class="variable">$(var2)</span>&quot;</span></span><br><span class="line">	@echo <span class="string">&quot;var3=<span class="variable">$(var3)</span>&quot;</span></span><br></pre></td></tr></table></figure><p>然后在终端运行 make test ，输出结果如下：</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">var1=main.o test.o</span><br><span class="line">var2=main.c test.c</span><br><span class="line">var3=main.c test.c</span><br></pre></td></tr></table></figure><p>可以发现所有的 .o 都被替换为 .c 。</p>
              </div>
            </details>

<h3 id="6-2-变量嵌套"><a href="#6-2-变量嵌套" class="headerlink" title="6.2 变量嵌套"></a><font size=3>6.2 变量嵌套</font></h3><p>变量的嵌套引用的具体含义是，我们可以在一个变量的赋值中引用其他的变量，并且引用变量的数量和和次数是不限制的。也就是说可以把变量的值再当成变量。例如，</p>
<figure class="highlight makefile"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">x = y</span><br><span class="line">y = z</span><br><span class="line">a := $(<span class="variable">$(x)</span>)</span><br><span class="line"><span class="section">test:</span></span><br><span class="line">	@echo <span class="string">&quot;x=<span class="variable">$(x)</span>&quot;</span></span><br><span class="line">	@echo <span class="string">&quot;y=<span class="variable">$(y)</span>&quot;</span></span><br><span class="line">	@echo <span class="string">&quot;a=<span class="variable">$(a)</span>&quot;</span></span><br></pre></td></tr></table></figure>

<p>然后在终端执行 make test ，会看到如下输出：</p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">x=y</span><br><span class="line">y=z</span><br><span class="line">a=z</span><br></pre></td></tr></table></figure>

<p>其实， $(x) 的值就是 y ，而外边还有一个 $ ，这样就会变成 $(y) 而 $(y)&#x3D;z ，所以最后就是 a&#x3D;$($(x))&#x3D;$(y)&#x3D;z 了。</p>
<p><strong>【说明】</strong>遇到这种变量嵌套的情况吗，我们就从最里层的 $ 开始向外一层一层进行分析即可。</p>
<h2 id="7-目标变量"><a href="#7-目标变量" class="headerlink" title="7. 目标变量"></a><font size=3>7. 目标变量</font></h2><h3 id="7-1-使用格式"><a href="#7-1-使用格式" class="headerlink" title="7.1 使用格式"></a><font size=3>7.1 使用格式</font></h3><p>我们可以为某个目标设置<strong>局部变量</strong>，这种变量被称为 Target-specific Variable 。一般语法格式如下：</p>
<figure class="highlight makefile"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">&lt;target ...&gt; : &lt;variable-assignment&gt;</span><br></pre></td></tr></table></figure>

<p>&lt;variable-assignment&gt; 可以是各种赋值表达式，如 &#x3D; 、 :&#x3D; 、 +&#x3D; 或是 ？&#x3D; 。</p>
<p><strong>【注意】</strong></p>
<p>目标变量<strong>可以和全局变量同名</strong>，因为它的<strong>作用范围只在这条规则以及连带规则中</strong>，所以其值也只在作用范围内有效，而不会影响规则链以外的全局变量的值。</p>
<h3 id="7-2-使用实例"><a href="#7-2-使用实例" class="headerlink" title="7.2 使用实例"></a><font size=3>7.2 使用实例</font></h3><details class="folding-tag" blue><summary> 点击查看实例 </summary>
              <div class='content'>
              <p> Makefile 文件内容如下：</p><figure class="highlight makefile"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">a := a.o b.o c.o</span><br><span class="line">test : a := main.o test.o</span><br><span class="line">test :</span><br><span class="line">	@echo <span class="string">&quot;a=<span class="variable">$(a)</span>&quot;</span></span><br><span class="line"><span class="section">a:</span></span><br><span class="line">	@echo <span class="string">&quot;a=<span class="variable">$(a)</span>&quot;</span> </span><br></pre></td></tr></table></figure><p>然后我们在终端中执行 make test ，会发现终端输出信息如下：</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">a=main.o test.o</span><br></pre></td></tr></table></figure><p>接着我们在终端中再执行 make a ，会发现终端中输出的信息如下：</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">a=a.o b.o c.o</span><br></pre></td></tr></table></figure><p>这也就说明了，目标变量仅仅在它自己的规则中有效，并且 make 会优先使用规则内定义的局部变量。</p>
              </div>
            </details>

<h1 id="二、Makefile-目标"><a href="#二、Makefile-目标" class="headerlink" title="二、Makefile 目标"></a><font size=3>二、Makefile 目标</font></h1><h2 id="1-特殊目标"><a href="#1-特殊目标" class="headerlink" title="1. 特殊目标"></a><font size=3>1. 特殊目标</font></h2><p> Makefile 中有很多特殊的目标，很可能都不会接触到，但是还是在这里写下笔记吧，万一后边用到了呢。</p>
<details class="folding-tag" blue><summary> 点击查看特殊目标 </summary>
              <div class='content'>
              <table>    <tr><td align="center" width=200px>名称</td><td align="center">功能</td></tr>    <tr><td align="center" width=200px>.PHONY</td><td align="left">这个目标的所有依赖被作为伪目标。伪目标是这样一个目标：当使用 make 命令行指定此目标时，这个目标所在的规则定义的命令、无论目标文件是否存在都会被无条件执行。</td></tr>    <tr><td align="center" width=200px>.SUFFIXES</td><td align="left">这个目标的所有依赖指出了一系列在后缀规则中需要检查的后缀名</td></tr>    <tr><td align="center" width=200px>.DEFAULT</td><td align="left">Makefile 中，这个特殊目标所在规则定义的命令，被用在重建那些没有具体规则的目标，就是说一个文件作为某个规则的依赖，却不是另外一个规则的目标时，make 程序无法找到重建此文件的规则，这种情况就执行 ".DEFAULT" 所指定的命令。</td></tr>    <tr><td align="center" width=200px>.PRECIOUS</td><td align="left">这个特殊目标所在的依赖文件在 make 的过程中会被特殊处理：当命令执行的过程中断时，make 不会删除它们。而且如果目标的依赖文件是中间过程文件，同样这些文件不会被删除。</td></tr>    <tr><td align="center" width=200px>.INTERMEDIATE</td><td align="left">这个特殊目标的依赖文件在 make 执行时被作为中间文件对待。没有任何依赖文件的这个目标没有意义。</td></tr>    <tr><td align="center" width=200px>.SECONDARY</td><td align="left">这个特殊目标的依赖文件被作为中过程的文件对待。但是这些文件不会被删除。这个目标没有任何依赖文件的含义是：将所有的文件视为中间文件。</td></tr>    <tr><td align="center" width=200px>.IGNORE</td><td align="left">这个目标的依赖文件忽略创建这个文件所执行命令的错误，给此目标指定命令是没有意义的。当此目标没有依赖文件时，将忽略所有命令执行的错误。</td></tr>    <tr><td align="center" width=200px>.DELETE_ON_ERROR</td><td align="left">如果在 Makefile 中存在特殊的目标 ".DELETE_ON_ERROR" ，make 在执行过程中，荣国规则的命令执行错误，将删除已经被修改的目标文件。</td></tr>    <tr><td align="center" width=200px>.LOW_RESOLUTION_TIME</td><td align="left">这个目标的依赖文件被 make 认为是低分辨率时间戳文件，给这个目标指定命令是没有意义的。通常的目标都是高分辨率时间戳。</td></tr>    <tr><td align="center" width=200px>.SILENT</td><td align="left">出现在此目标 ".SILENT" 的依赖文件列表中的文件，make 在创建这些文件时，不打印出此文件所执行的命令。同样，给目标 "SILENT" 指定命令行是没有意义的。</td></tr>    <tr><td align="center" width=200px>.EXPORT_ALL_VARIABLES</td><td align="left">此目标应该作为一个简单的没有依赖的目标，它的功能是将之后的所有变量传递给子 make 进程。</td></tr>    <tr><td align="center" width=200px>.NOTPARALLEL</td><td align="left"> Makefile 中如果出现这个特殊目标，则所有的命令按照串行的方式执行，即使是存在 make 的命令行参数 "-j" 。但在递归调用的子make进程中，命令行可以并行执行。此目标不应该有依赖文件，所有出现的依赖文件将会被忽略。</td></tr></table>
              </div>
            </details>

<h2 id="2-伪目标"><a href="#2-伪目标" class="headerlink" title="2.伪目标"></a><font size=3>2.伪目标</font></h2><p>还记得前边提到的 .PHONY:clean 把，当时说这是一个伪目标，但是并未说明啥叫伪目标，伪目标有啥用，接下来，就来探索一下吧。</p>
<h3 id="2-1-一个问题？"><a href="#2-1-一个问题？" class="headerlink" title="2.1 一个问题？"></a><font size=3>2.1 一个问题？</font></h3><p>还是以 clean 这个清除操作为例，我们在编译过后，会生成大量的中间文件，当我们定义了 clean 命令后，却并不需要依赖于任何文件，而且也不需要生成任何文件，我们只需要执行这个规则下边的命令即可.</p>
<p>正常情况下，我们执行 make clean 命令就可以执行 clean 目标下的文件，但是如果说 Makefile 文件所在目录下刚好有一个文件叫 clean ，由于这个文件不依赖于任何文件，也不会被修改，所以，它永远都是<strong>最新</strong>的。于是，我们除了第一次执行 make clean 命令有效外，再执行的时候，就会发现 make 一直会提醒：</p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">make: “clean”已是最新。</span><br></pre></td></tr></table></figure>

<p> make 只会处理修改过的文件，为我们带来便利的同时，也为我们带来了隐藏的麻烦，也就是说我们的目标名不能与某一个文件名一致。</p>
<h3 id="2-2-怎么办呢？"><a href="#2-2-怎么办呢？" class="headerlink" title="2.2 怎么办呢？"></a><font size=3>2.2 怎么办呢？</font></h3><p>为了解决上边的问题，我们可以使用一种特殊的目标 .PHONY ， make 不会去检查是否存在有文件名和依赖体中的一个名字相匹配的文件，而是直接执行与之相关的命令，于是这也就被称为<strong>伪目标</strong>。 make 后不会生成与伪目标同名的文件，伪目标只是一个<strong>标签</strong>。</p>
<p>总的来说，<strong>伪目标的作用</strong>其实就是为了<strong>避免目标名与文件名冲突</strong>。那么怎么声明伪目标呢？语法格式如下：</p>
<figure class="highlight makefile"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta"><span class="keyword">.PHONY</span>: object</span></span><br><span class="line"><span class="section">object:</span></span><br><span class="line">&lt;Tab&gt;[option]command</span><br></pre></td></tr></table></figure>

<p>其实一开始的 clean 就是一个很好的例子：</p>
<figure class="highlight makefile"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta"><span class="keyword">.PHONY</span>: clean</span></span><br><span class="line"><span class="section">clean:</span></span><br><span class="line">    rm -rf *.o main</span><br></pre></td></tr></table></figure>

<p>伪目标一般没有依赖的文件。但是，我们也可以为伪目标指定所依赖的文件。伪目标说到底也算是一个目标，同样可以作为<strong>最终目标</strong>，只要将其放在第一个即可。</p>
<p>其实，<strong>只要目标名称不要与某一个文件名称一致，不用声明成伪目标也可以</strong>，但是建议还是注意一下这个问题。</p>
<h3 id="2-3-成为依赖"><a href="#2-3-成为依赖" class="headerlink" title="2.3 成为依赖"></a><font size=3>2.3 成为依赖</font></h3><p>伪目标可以成为依赖，这是什么意思呢？接下来我们来看一个例子：</p>
<figure class="highlight makefile"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta"><span class="keyword">.PHONY</span>: clean clean-o</span></span><br><span class="line"><span class="section">clean: clean-o</span></span><br><span class="line">    rm -rf main</span><br><span class="line"><span class="section">clean-o: </span></span><br><span class="line">    rm -rf *.o</span><br></pre></td></tr></table></figure>

<p>这样的话，我们执行 make clean 命令会清除所有的 .o 文件和 main 可执行文件，执行 main clean-o 便会只清除所有的 .o 文件。这样我们就可以通过执行不同的命令来删除一部分文件，而保留不想删除的文件。</p>
<h2 id="3-多目标"><a href="#3-多目标" class="headerlink" title="3. 多目标"></a><font size=3>3. 多目标</font></h2><p>啥又是多目标嘞？简单来说就是一个 Makefile 文件，直接生成多个可执行文件， Makefile 文件每次只能有一个最终目标，也就是说正常情况下，只会有一个可执行文件，加上一堆的中间文件。</p>
<h3 id="3-1-单目标测试"><a href="#3-1-单目标测试" class="headerlink" title="3.1 单目标测试"></a><font size=3>3.1 单目标测试</font></h3><p>其实我们可以试一下在一个 Makefile 中写上两个可执行文件的编译链接规则，然后执行 make 来看看最后输出多少个可执行文件。</p>
<details class="folding-tag" blue><summary> 点击查看Makefile 文件 </summary>
              <div class='content'>
              <figure class="highlight makefile"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br></pre></td><td class="code"><pre><span class="line">OBJ = main.o test1.o test2.o</span><br><span class="line"><span class="comment"># 可执行程序 main</span></span><br><span class="line"><span class="section">main: $&#123;OBJ&#125;</span></span><br><span class="line">	gcc <span class="variable">$(OBJ)</span> -o main</span><br><span class="line"></span><br><span class="line"><span class="section">main.o: main.c test.h</span></span><br><span class="line">	gcc -c main.c -o main.o</span><br><span class="line"><span class="section">test1.o: test1.c test.h</span></span><br><span class="line">	gcc -c test1.c -o test1.o</span><br><span class="line"><span class="section">test2.o: test2.c test.h</span></span><br><span class="line">	gcc -c test2.c -o test2.o</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="comment"># 可执行程序 main-copy</span></span><br><span class="line"><span class="section">main-copy: main-copy.o</span></span><br><span class="line">	gcc main-copy.o -o main-copy</span><br><span class="line"></span><br><span class="line"><span class="section">main-copy.o: main-copy.c</span></span><br><span class="line">	gcc -c main-copy.c -o main-copy.o</span><br><span class="line"></span><br><span class="line"><span class="meta"><span class="keyword">.PHONY</span>: clean</span></span><br><span class="line"><span class="section">clean:</span></span><br><span class="line">	rm -rf *.o main main-copy</span><br></pre></td></tr></table></figure>
              </div>
            </details>

<details class="folding-tag" blue><summary> 点击查看相关文件内容 </summary>
              <div class='content'>
              <p>【说明】目前所有文件都在同一个目录下。</p><div class="tabs" id="tabname2"><ul class="nav-tabs"><li class="tab active"><a href="#tabname2-1">main.c</a></li><li class="tab"><a href="#tabname2-2">main-copy.c</a></li><li class="tab"><a href="#tabname2-3">test1.c</a></li><li class="tab"><a href="#tabname2-4">test2.c</a></li><li class="tab"><a href="#tabname2-5">test.h</a></li></ul><div class="tab-content"><div class="tab-pane active" id="tabname2-1"><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;stdio.h&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&quot;test.h&quot;</span></span></span><br><span class="line"></span><br><span class="line"><span class="type">int</span> <span class="title function_">main</span><span class="params">(<span class="type">int</span> argc, <span class="type">const</span> <span class="type">char</span> *argv[])</span></span><br><span class="line">&#123;</span><br><span class="line">	<span class="built_in">printf</span>(<span class="string">&quot;This is main file!\n&quot;</span>);</span><br><span class="line">	test1Fun();</span><br><span class="line">	test2Fun();</span><br><span class="line">	<span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure></div><div class="tab-pane" id="tabname2-2"><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;stdio.h&gt;</span></span></span><br><span class="line"></span><br><span class="line"><span class="type">int</span> <span class="title function_">main</span><span class="params">(<span class="type">int</span> argc, <span class="type">const</span> <span class="type">char</span> *argv[])</span></span><br><span class="line">&#123;</span><br><span class="line">	<span class="built_in">printf</span>(<span class="string">&quot;This is main-copy file!\n&quot;</span>);</span><br><span class="line"></span><br><span class="line">	<span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure></div><div class="tab-pane" id="tabname2-3"><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;stdio.h&gt;</span></span></span><br><span class="line"></span><br><span class="line"><span class="type">void</span> <span class="title function_">test1Fun</span><span class="params">()</span></span><br><span class="line">&#123;</span><br><span class="line">    <span class="built_in">printf</span>(<span class="string">&quot;This is test1.c file\n&quot;</span>);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure></div><div class="tab-pane" id="tabname2-4"><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;stdio.h&gt;</span></span></span><br><span class="line"></span><br><span class="line"><span class="type">void</span> <span class="title function_">test2Fun</span><span class="params">()</span></span><br><span class="line">&#123;</span><br><span class="line">    <span class="built_in">printf</span>(<span class="string">&quot;This is test2.c file\n&quot;</span>);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure></div><div class="tab-pane" id="tabname2-5"><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="type">void</span> <span class="title function_">test1Fun</span><span class="params">()</span>;</span><br><span class="line"><span class="type">void</span> <span class="title function_">test2Fun</span><span class="params">()</span>;</span><br></pre></td></tr></table></figure></div></div></div>
              </div>
            </details>

<p>然后在终端执行 make 命令，会发现生成了与 main 目标相关的可执行文件和中间文件，但是 main-copy 目标没有生成，也没有生成中间文件。这个时候我们执行 make main-copy ，会发现，这个时候相应的目标才会生成。</p>
<p>所以说，一般情况下，一个 Makefile 文件只通过 make 命令一般只会生成一个最终目标，但是想要生成两个甚至多个也不是不可以。</p>
<h3 id="3-2-多目标生成方式一"><a href="#3-2-多目标生成方式一" class="headerlink" title="3.2 多目标生成方式一"></a><font size=3>3.2 多目标生成方式一</font></h3><p>其实很容易想到，上边我们不是学习了伪目标嘛，它是不生成文件的，但是它是可以放在文件开头充当最终目标的，于是我们可以修改 Makefile 文件如下：</p>
<details class="folding-tag" blue><summary> 点击查看Makefile 文件 </summary>
              <div class='content'>
              <figure class="highlight makefile"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br></pre></td><td class="code"><pre><span class="line"><span class="section">all: main main-copy</span></span><br><span class="line">	@echo <span class="string">&quot;Start!&quot;</span></span><br><span class="line"><span class="meta"><span class="keyword">.PHONY</span>: all</span></span><br><span class="line"></span><br><span class="line">OBJ = main.o test1.o test2.o</span><br><span class="line"><span class="comment"># 可执行程序 main</span></span><br><span class="line"><span class="section">main: $&#123;OBJ&#125;</span></span><br><span class="line">	gcc <span class="variable">$(OBJ)</span> -o main</span><br><span class="line"></span><br><span class="line"><span class="section">main.o: main.c test.h</span></span><br><span class="line">	gcc -c main.c -o main.o</span><br><span class="line"><span class="section">test1.o: test1.c test.h</span></span><br><span class="line">	gcc -c test1.c -o test1.o</span><br><span class="line"><span class="section">test2.o: test2.c test.h</span></span><br><span class="line">	gcc -c test2.c -o test2.o</span><br><span class="line"></span><br><span class="line"><span class="comment"># 可执行程序 main-copy</span></span><br><span class="line"><span class="section">main-copy: main-copy.o</span></span><br><span class="line">	gcc main-copy.o -o main-copy</span><br><span class="line"></span><br><span class="line"><span class="section">main-copy.o: main-copy.c</span></span><br><span class="line">	gcc -c main-copy.c -o main-copy.o</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="meta"><span class="keyword">.PHONY</span>: clean</span></span><br><span class="line"><span class="section">clean:</span></span><br><span class="line">	rm -rf *.o main main-copy</span><br></pre></td></tr></table></figure><p>【说明】有的 Makefile 可能不会标明 .PHONY: all 这一句，如果能保证工程文件和生成文件没有与伪目标同名的文件的话，不写也是不会有问题的，不写的话可以理解为标签，写的话可以理解为伪目标（<strong>伪目标和标签都不会生成相应的文件</strong>）。</p>
              </div>
            </details>

<details class="folding-tag" blue><summary> 点击查看相关文件内容 </summary>
              <div class='content'>
              <p>【说明】目前所有文件都在同一个目录下。</p><div class="tabs" id="tabname3"><ul class="nav-tabs"><li class="tab active"><a href="#tabname3-1">main.c</a></li><li class="tab"><a href="#tabname3-2">main-copy.c</a></li><li class="tab"><a href="#tabname3-3">test1.c</a></li><li class="tab"><a href="#tabname3-4">test2.c</a></li><li class="tab"><a href="#tabname3-5">test.h</a></li></ul><div class="tab-content"><div class="tab-pane active" id="tabname3-1"><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;stdio.h&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&quot;test.h&quot;</span></span></span><br><span class="line"></span><br><span class="line"><span class="type">int</span> <span class="title function_">main</span><span class="params">(<span class="type">int</span> argc, <span class="type">const</span> <span class="type">char</span> *argv[])</span></span><br><span class="line">&#123;</span><br><span class="line">	<span class="built_in">printf</span>(<span class="string">&quot;This is main file!\n&quot;</span>);</span><br><span class="line">	test1Fun();</span><br><span class="line">	test2Fun();</span><br><span class="line">	<span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure></div><div class="tab-pane" id="tabname3-2"><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;stdio.h&gt;</span></span></span><br><span class="line"></span><br><span class="line"><span class="type">int</span> <span class="title function_">main</span><span class="params">(<span class="type">int</span> argc, <span class="type">const</span> <span class="type">char</span> *argv[])</span></span><br><span class="line">&#123;</span><br><span class="line">	<span class="built_in">printf</span>(<span class="string">&quot;This is main-copy file!\n&quot;</span>);</span><br><span class="line"></span><br><span class="line">	<span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure></div><div class="tab-pane" id="tabname3-3"><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;stdio.h&gt;</span></span></span><br><span class="line"></span><br><span class="line"><span class="type">void</span> <span class="title function_">test1Fun</span><span class="params">()</span></span><br><span class="line">&#123;</span><br><span class="line">    <span class="built_in">printf</span>(<span class="string">&quot;This is test1.c file\n&quot;</span>);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure></div><div class="tab-pane" id="tabname3-4"><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;stdio.h&gt;</span></span></span><br><span class="line"></span><br><span class="line"><span class="type">void</span> <span class="title function_">test2Fun</span><span class="params">()</span></span><br><span class="line">&#123;</span><br><span class="line">    <span class="built_in">printf</span>(<span class="string">&quot;This is test2.c file\n&quot;</span>);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure></div><div class="tab-pane" id="tabname3-5"><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="type">void</span> <span class="title function_">test1Fun</span><span class="params">()</span>;</span><br><span class="line"><span class="type">void</span> <span class="title function_">test2Fun</span><span class="params">()</span>;</span><br></pre></td></tr></table></figure></div></div></div>
              </div>
            </details>

<p>然后，我们在终端中再次执行 make ，这个时候就会发现，生成了两个可执行文件 main 和 main-copy 。</p>
<h3 id="3-3-多目标生成方式二"><a href="#3-3-多目标生成方式二" class="headerlink" title="3.3 多目标生成方式二"></a><font size=3>3.3 多目标生成方式二</font></h3><p>上边的其实是通过伪目标的方式来达到生成多个目标文件的方式，总的来说还是一个规则只有一个目标，是多个单目标的规则。</p>
<p>而 Makefile 还支持一个规则中有多个目标，这个多目标规则所定义的命令对所有目标都生效，一个具有多目标的规则相当于定义了多个单目标规则，但是它们执行的命令类似。<strong>多目标规则意味着所有的目标具有相同的依赖文件</strong>。</p>
<p>多目标通常用于以下情况：</p>
<p>（1）仅需要一个描述依赖关系的规则，不需要在规则中定义命令。例如，</p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta prompt_"># </span><span class="language-bash">这个规则实现了同时给三个目标文件指定一个依赖文件</span></span><br><span class="line">main.o test1.o test2.o: test.h</span><br></pre></td></tr></table></figure>

<p>（2）对于多个具有类似重建命令的目标。重建这些目标的命令并不需要是完全相同，我们可以在命令行中使用自动化变量 $@ 来引用具体的目标，完成对它们的重建。</p>
<details class="folding-tag" blue><summary> 点击查看实例 </summary>
              <div class='content'>
              <p>【说明】其实这里我不是很理解😅，但是网上有一个《跟我一起写Makefile》的文档，还有很多资料上都举了这个例子，说实话，学到这里的时候我还是不理解这个例子，由于还没用到过，暂时先写在这，后续用到了再更新这里的笔记。</p><figure class="highlight makefile"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line">bigoutput littleoutput : text.g</span><br><span class="line">	generate text.g -<span class="variable">$(<span class="built_in">subst</span> output,,<span class="variable">$@</span>)</span> &gt; <span class="variable">$@</span></span><br><span class="line">	</span><br><span class="line"><span class="comment"># 上边的就等价于</span></span><br><span class="line"></span><br><span class="line">bigoutput : text.g</span><br><span class="line">	generate text.g -big &gt; bigoutput</span><br><span class="line">littleoutput : text.g</span><br><span class="line">	generate text.g -little &gt; littleoutput</span><br></pre></td></tr></table></figure><p>上边的 generate 根据命令行参数来决定输出文件的类型。使用了 make 的字符串处理函数 subst 来根据目标产生对应的命令行选项。</p>
              </div>
            </details>

<p>在多目标的规则中，虽然可以根据不同的目标使用不同的命令(在命令行中使用自动化变量 $@ )。但是，多目标的规则并不能做到根据目标文件自动改变依赖文件(像上边例子中使用自动化变量 $@ 改变规则的命令一样)。需要实现这个目的的话，需要要用到 make 的静态模式。</p>
<h2 id="4-多规则目标"><a href="#4-多规则目标" class="headerlink" title="4. 多规则目标"></a><font size=3>4. 多规则目标</font></h2><h3 id="4-1-规则"><a href="#4-1-规则" class="headerlink" title="4.1 :: 规则"></a><font size=3>4.1 :: 规则</font></h3><p>看完上边的，我会想，那要是我一个目标需要多个规则来完成怎么办？这个时候我们可以使用 :: 双冒号，这种规则也可以被称之为双冒号规则。</p>
<p>双冒号规则允许在多个规则中为同一个目标指定不同的重建目标的命令。</p>
<p>在 Makefile 中，一个目标可以出现在多个规则中，但是这些规则必须是同一类型的，要么都是普通规则，要么都是双冒号规则，<strong>坚决不允许一个目标出现在两种规则中</strong>。</p>
<ul>
<li>双冒号规则与普通规则的不同</li>
</ul>
<p>（1）双冒号规则中，当依赖文件比目标更新时，规则将会被执行。对于一个没有依赖而只有命令行的双冒号规则，当引用此目标时，规则的命令将会被无条件执行。而普通规则是，当规则的目标文件存在时，此规则的命令永远不会被执行（目标文件永远是最新的）。</p>
<p>（2）当同一个文件作为多个双冒号规则的目标时，这些不同的规则会被独立的处理，而不是像普通规则那样合并所有的依赖到一个目标文件。这就意味着对这些规则的处理就像多个不同的普通规则一样。也就是说多个双冒号规则中的每一个的依赖文件被改变之后， make 只执行此规则定义的命令，而其它的以这个文件作为目标的双冒号规则将不会被执行。</p>
<p>【注意】同一个目标出现在多个双冒号规则中时，规则的执行顺序和普通规则的执行顺序一样，按照其在 Makefile 文件中的书写顺序执行。</p>
<h3 id="4-2-使用实例-1"><a href="#4-2-使用实例-1" class="headerlink" title="4.2 使用实例"></a><font size=3>4.2 使用实例</font></h3><p>其实学习到这里的时候我是很疑惑的，目前为止还没有遇到过这样的目标，下边的例子中，执行最终的可执行程序的时候，打印的内容是相同的，所以目前为止，我还不是很清楚这个规则究竟有什么用处，先写在这里吧，后边懂了再补充笔记。</p>
<details class="folding-tag" blue><summary> 点击查看实例 </summary>
              <div class='content'>
              <details class="folding-tag" blue><summary> 点击查看相关文件内容 </summary>              <div class='content'>              <div class="tabs" id="tabname4"><ul class="nav-tabs"><li class="tab active"><a href="#tabname4-1">main.c</a></li><li class="tab"><a href="#tabname4-2">test.c</a></li></ul><div class="tab-content"><div class="tab-pane active" id="tabname4-1"><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;stdio.h&gt;</span></span></span><br><span class="line"></span><br><span class="line"><span class="type">int</span> <span class="title function_">main</span><span class="params">(<span class="type">int</span> argc, <span class="type">const</span> <span class="type">char</span> *argv[])</span></span><br><span class="line">&#123;</span><br><span class="line">	<span class="built_in">printf</span>(<span class="string">&quot;This is main file!\n&quot;</span>);</span><br><span class="line"></span><br><span class="line">	<span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">	</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure></div><div class="tab-pane" id="tabname4-2"><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;stdio.h&gt;</span></span></span><br><span class="line"></span><br><span class="line"><span class="type">int</span> <span class="title function_">main</span><span class="params">(<span class="type">int</span> argc, <span class="type">const</span> <span class="type">char</span> *argv[])</span></span><br><span class="line">&#123;</span><br><span class="line">	<span class="built_in">printf</span>(<span class="string">&quot;This is test file!\n&quot;</span>);</span><br><span class="line"></span><br><span class="line">	<span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">	</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure></div></div></div>              </div>            </details><div class="tabs" id="tabname5"><ul class="nav-tabs"><li class="tab active"><a href="#tabname5-1">普通规则</a></li><li class="tab"><a href="#tabname5-2">双冒号规则</a></li></ul><div class="tab-content"><div class="tab-pane active" id="tabname5-1"><p> Makefile 文件如下：</p><figure class="highlight makefile"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="section">main: main.c</span></span><br><span class="line">	gcc <span class="variable">$&lt;</span> -o <span class="variable">$@</span></span><br><span class="line"><span class="section">main: test.c</span></span><br><span class="line">	gcc <span class="variable">$&lt;</span> -o <span class="variable">$@</span></span><br><span class="line"></span><br><span class="line"><span class="meta"><span class="keyword">.PHONY</span>: clean</span></span><br><span class="line"><span class="section">clean:</span></span><br><span class="line">	rm -rf *.o main</span><br></pre></td></tr></table></figure><p>在终端执行 make ，会发现有如下输出内容：</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">Makefile:4: 警告：覆盖关于目标“main”的配方</span><br><span class="line">Makefile:2: 警告：忽略关于目标“main”的旧配方</span><br><span class="line">gcc test.c -o main</span><br></pre></td></tr></table></figure><p>即便有警告，但是依然输出了相应的 main 可执行文件。</p></div><div class="tab-pane" id="tabname5-2"><p> Makefile 文件如下：</p><figure class="highlight makefile"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="section">main:: main.c</span></span><br><span class="line">	gcc <span class="variable">$&lt;</span> -o <span class="variable">$@</span></span><br><span class="line"><span class="section">main:: test.c</span></span><br><span class="line">	gcc <span class="variable">$&lt;</span> -o <span class="variable">$@</span></span><br><span class="line"></span><br><span class="line"><span class="meta"><span class="keyword">.PHONY</span>: clean</span></span><br><span class="line"><span class="section">clean:</span></span><br><span class="line">	rm -rf *.o main</span><br></pre></td></tr></table></figure><p>在终端执行 make ，会发现正常输出了，也没有警告。此时如果 main.c 文件被修改了， main 将会根据 main.c 被重建，如果 test.c 文件被修改了， main 将会根据 test.c 被重建。</p></div></div></div>
              </div>
            </details>


    </div>

    
    
    

    <footer class="post-footer">




    <div>
        
            <div style="text-align:center;color: #ccc;font-size:14px;">
            ----------本文结束
            <i class="fas fa-fan fa-spin" style="color: #FF1493; font-size: 1rem"></i>
            感谢您的阅读----------
            </div>
        
    </div>





  
  <div class="my_post_copyright"> 
    <p><span>文章标题:</span><a href="/post/f9611cfe.html">LV02-05-Makefile-02-变量和目标</a></p>
    <p><span>文章作者:</span><a href="/" title="欢迎访问 《苏木》 的学习笔记">苏木</a></p>
    <p><span>发布时间:</span>2022年03月23日 - 13:53</p>
    <p><span>最后更新:</span>2025年06月14日 - 00:25</p>
    <p><span>原始链接:</span><a href="/post/f9611cfe.html" title="LV02-05-Makefile-02-变量和目标">https://sumumm.github.io/post/f9611cfe.html</a></p>
    <p><span>许可协议:</span><i class="fab fa-creative-commons"></i> <a rel="license" href= "https://creativecommons.org/licenses/by-nc-nd/4.0/" target="_blank" title="Attribution-NonCommercial-NoDerivatives 4.0 International (CC BY-NC-ND 4.0)">署名-非商业性使用-禁止演绎 4.0 国际</a> 转载请保留原文链接及作者。</p>  
  </div>
  


          <div class="post-tags">
              <a href="/tags/LV02-%E7%BC%96%E8%AF%91%E5%9F%BA%E7%A1%80/" rel="tag"><i class="fa fa-tag"></i> LV02-编译基础</a>
              <a href="/tags/makefile/" rel="tag"><i class="fa fa-tag"></i> makefile</a>
          </div>

        

          <div class="post-nav">
            <div class="post-nav-item">
                <a href="/post/592fcb59.html" rel="prev" title="LV02-05-Makefile-03-make命令与传参">
                  <i class="fa fa-angle-left"></i> LV02-05-Makefile-03-make命令与传参
                </a>
            </div>
            <div class="post-nav-item">
                <a href="/post/f2f92586.html" rel="next" title="LV02-05-Makefile-01-基础知识">
                  LV02-05-Makefile-01-基础知识 <i class="fa fa-angle-right"></i>
                </a>
            </div>
          </div>
    </footer>
  </article>
</div>






</div>
  </main>

  <footer class="footer">
    <div class="footer-inner">

  <div class="copyright">
    &copy; 2017 – 
    <span itemprop="copyrightYear">2025</span>
    <span class="with-love">
      <i class="fa fa-heart"></i>
    </span>
    <span class="author" itemprop="copyrightHolder">苏木</span>
  </div>
<div class="wordcount">
  <span class="post-meta-item">
    <span class="post-meta-item-icon">
      <i class="fa fa-chart-line"></i>
    </span>
      <span>站点总字数：</span>
    <span title="站点总字数">3.7m</span>
  </span>
  <span class="post-meta-item">
    <span class="post-meta-item-icon">
      <i class="fa fa-coffee"></i>
    </span>
      <span>站点阅读时长 &asymp;</span>
    <span title="站点阅读时长">225:26</span>
  </span>
</div>




    <span id="sitetime"></span>
    <script defer language=javascript>
        function siteTime()
        {
            window.setTimeout("siteTime()", 1000);
            var seconds = 1000;
            var minutes = seconds * 60;
            var hours = minutes * 60;
            var days = hours * 24;
            var years = days * 365;
            var today = new Date();
            var todayYear = today.getFullYear();
            var todayMonth = today.getMonth()+1;
            var todayDate = today.getDate();
            var todayHour = today.getHours();
            var todayMinute = today.getMinutes();
            var todaySecond = today.getSeconds();
            /*==================================================
            Date.UTC() -- 返回date对象距世界标准时间(UTC)1970年1月1日午夜之间的毫秒数(时间戳)
            year        - 作为date对象的年份，为4位年份值
            month       - 0-11之间的整数，做为date对象的月份
            day         - 1-31之间的整数，做为date对象的天数
            hours       - 0(午夜24点)-23之间的整数，做为date对象的小时数
            minutes     - 0-59之间的整数，做为date对象的分钟数
            seconds     - 0-59之间的整数，做为date对象的秒数
            microseconds - 0-999之间的整数，做为date对象的毫秒数
            ==================================================*/
            var t1 = Date.UTC(2017, 
                              5, 
                              19, 
                              0, 
                              0, 
                              0); //北京时间
            var t2 = Date.UTC(todayYear,todayMonth,todayDate,todayHour,todayMinute,todaySecond);
            var diff = t2-t1;
            var diffYears = Math.floor(diff/years);
            var diffDays = Math.floor((diff/days)-diffYears*365);
            var diffHours = Math.floor((diff-(diffYears*365+diffDays)*days)/hours);
            var diffMinutes = Math.floor((diff-(diffYears*365+diffDays)*days-diffHours*hours)/minutes);
            var diffSeconds = Math.floor((diff-(diffYears*365+diffDays)*days-diffHours*hours-diffMinutes*minutes)/seconds);
            document.getElementById("sitetime").innerHTML="已在这里 "+diffYears+" 年 "+diffDays+" 天 "+diffHours+" 小时 "+diffMinutes+" 分钟 "+diffSeconds+" 秒";
        }
        siteTime();
    </script>



    </div>
  </footer>

  
  <div class="back-to-top" role="button" aria-label="返回顶部">
    <i class="fa fa-arrow-up fa-lg"></i>
    <span>0%</span>
  </div>
  <div class="reading-progress-bar"></div>

<noscript>
  <div class="noscript-warning">Theme NexT works best with JavaScript enabled</div>
</noscript>


  
  <script src="https://cdnjs.cloudflare.com/ajax/libs/animejs/3.2.1/anime.min.js" integrity="sha256-XL2inqUJaslATFnHdJOi9GfQ60on8Wx1C2H8DYiN1xY=" crossorigin="anonymous"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/next-theme-pjax/0.6.0/pjax.min.js" integrity="sha256-vxLn1tSKWD4dqbMRyv940UYw4sXgMtYcK6reefzZrao=" crossorigin="anonymous"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/fancyapps-ui/5.0.28/fancybox/fancybox.umd.js" integrity="sha256-ytMJGN3toR+a84u7g7NuHm91VIR06Q41kMWDr2pq7Zo=" crossorigin="anonymous"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/lozad.js/1.16.0/lozad.min.js" integrity="sha256-mOFREFhqmHeQbXpK2lp4nA3qooVgACfh88fpJftLBbc=" crossorigin="anonymous"></script>
<script src="/js/comments.js"></script><script src="/js/utils.js"></script><script src="/js/motion.js"></script><script src="/js/next-boot.js"></script><script src="/js/pjax.js"></script>

  <script src="https://cdnjs.cloudflare.com/ajax/libs/hexo-generator-searchdb/1.4.1/search.js" integrity="sha256-1kfA5uHPf65M5cphT2dvymhkuyHPQp5A53EGZOnOLmc=" crossorigin="anonymous"></script>
<script src="/js/third-party/search/local-search.js"></script>




  <script src="/js/third-party/fancybox.js"></script>

  <script src="/js/third-party/pace.js"></script>


  




  

  <script class="next-config" data-name="enableMath" type="application/json">false</script><script class="next-config" data-name="mathjax" type="application/json">{"enable":true,"tags":"none","js":{"url":"https://cdnjs.cloudflare.com/ajax/libs/mathjax/3.2.2/es5/tex-mml-chtml.js","integrity":"sha256-MASABpB4tYktI2Oitl4t+78w/lyA+D7b/s9GEP0JOGI="}}</script>
<script src="/js/third-party/math/mathjax.js"></script>


 
        <div id="click-show-text"
            data-mobile = false
            data-text = 富强,民主,文明,和谐,自由,平等,公正,法制,爱国,敬业,诚信,友善
            data-fontsize = 15px
            data-random= false>
        </div>
       

      
        <script async src=https://cdn.jsdelivr.net/npm/hexo-next-mouse-effect@latest/click/showText.js></script>
      

      
    




    <script async src="/js/fancybox_param.js"></script>





<!-- APlayer本体 -->



</body>
</html>
